package dao;

import model.*;

import java.io.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DataManager {
    private Map<String, User> users = new HashMap<>();
    private Map<String, Movie> movies = new HashMap<>();
    private Map<String, Hall> halls = new HashMap<>();
    private Map<String, Screening> screenings = new HashMap<>();
    private List<LogEntry> logs = new ArrayList<>();
    private SaleStatistics saleStatistics = new SaleStatistics();
    private Map<String, Ticket> tickets = new HashMap<>();
    
    private static final String DATA_FILE = "cinema_data.dat";
    
    private static DataManager instance;
    
    private DataManager() {
        initDefaultData();
    }
    
    public static DataManager getInstance() {
        if (instance == null) {
            instance = new DataManager();
            instance.loadData();
        }
        return instance;
    }
    
    private void initDefaultData() {
        // 初始化默认管理员账户
        if (users.isEmpty()) {
            User adminUser = new User("admin", "admin", "ynuinfo#777", UserType.ADMIN, "13800000000");
            users.put(adminUser.getUsername(), adminUser);
            
            // 初始化放映厅
            Hall goldHall = new Hall("hall1", "黄金厅", 8, 10);
            Hall silverHall = new Hall("hall2", "白银厅", 10, 12);
            Hall jadeHall = new Hall("hall3", "翡翠厅", 7, 8);
            Hall diamondHall = new Hall("hall4", "钻石厅", 7, 8);
            Hall gemHall = new Hall("hall5", "宝石厅", 8, 9);
            
            halls.put(goldHall.getId(), goldHall);
            halls.put(silverHall.getId(), silverHall);
            halls.put(jadeHall.getId(), jadeHall);
            halls.put(diamondHall.getId(), diamondHall);
            halls.put(gemHall.getId(), gemHall);
        }
    }
    
    // 用户管理相关方法
    public boolean addUser(User user) {
        if (users.containsKey(user.getUsername())) {
            return false;
        }
        users.put(user.getUsername(), user);
        saveData();
        return true;
    }
    
    public User getUserByUsername(String username) {
        return users.get(username);
    }
    
    public User getUserById(String id) {
        for (User user : users.values()) {
            if (user.getId().equals(id)) {
                return user;
            }
        }
        return null;
    }
    
    public boolean deleteUser(String username) {
        if (!username.equals("admin")) {
            users.remove(username);
            saveData();
            return true;
        }
        return false;
    }
    
    public List<User> getAllUsers() {
        return new ArrayList<>(users.values());
    }
    
    public boolean updateUser(User user) {
        if (users.containsKey(user.getUsername())) {
            users.put(user.getUsername(), user);
            saveData();
            return true;
        }
        return false;
    }
    
    // 电影管理相关方法
    public boolean addMovie(Movie movie) {
        movies.put(movie.getId(), movie);
        saveData();
        return true;
    }
    
    public Movie getMovieById(String id) {
        return movies.get(id);
    }
    
    public boolean deleteMovie(String id) {
        // 检查电影是否有场次正在上映
        for (Screening screening : screenings.values()) {
            if (screening.getMovie().getId().equals(id) && 
                screening.getStartTime().isAfter(LocalDateTime.now())) {
                return false;
            }
        }
        
        movies.remove(id);
        saveData();
        return true;
    }
    
    public List<Movie> getAllMovies() {
        return new ArrayList<>(movies.values());
    }
    
    public List<Movie> searchMovies(String title, String director, String actors) {
        List<Movie> result = new ArrayList<>();
        
        for (Movie movie : movies.values()) {
            boolean titleMatch = title == null || title.isEmpty() || movie.getTitle().contains(title);
            boolean directorMatch = director == null || director.isEmpty() || movie.getDirector().contains(director);
            boolean actorsMatch = actors == null || actors.isEmpty() || movie.getActors().contains(actors);
            
            if (titleMatch && directorMatch && actorsMatch) {
                result.add(movie);
            }
        }
        
        return result;
    }
    
    public boolean updateMovie(Movie movie) {
        if (movies.containsKey(movie.getId())) {
            movies.put(movie.getId(), movie);
            saveData();
            return true;
        }
        return false;
    }
    
    // 放映厅相关方法
    public Hall getHallById(String id) {
        return halls.get(id);
    }
    
    public List<Hall> getAllHalls() {
        return new ArrayList<>(halls.values());
    }
    
    // 场次管理相关方法
    public boolean addScreening(Screening screening) {
        screenings.put(screening.getId(), screening);
        saveData();
        return true;
    }
    
    public Screening getScreeningById(String id) {
        return screenings.get(id);
    }
    
    public boolean deleteScreening(String id) {
        // 检查场次是否有已售票
        Screening screening = screenings.get(id);
        if (screening != null) {
            for (Ticket ticket : tickets.values()) {
                if (ticket.getScreening().getId().equals(id) && 
                    ticket.getStatus() != TicketStatus.REFUNDED) {
                    return false;
                }
            }
        }
        
        screenings.remove(id);
        saveData();
        return true;
    }
    
    public boolean updateScreening(Screening screening) {
        // 检查场次是否有已售票
        Screening oldScreening = screenings.get(screening.getId());
        if (oldScreening != null) {
            for (Ticket ticket : tickets.values()) {
                if (ticket.getScreening().getId().equals(screening.getId()) && 
                    ticket.getStatus() != TicketStatus.REFUNDED) {
                    return false;
                }
            }
        }
        
        screenings.put(screening.getId(), screening);
        saveData();
        return true;
    }
    
    public List<Screening> getAllScreenings() {
        return new ArrayList<>(screenings.values());
    }
    
    // 票务管理相关方法
    public boolean addTicket(Ticket ticket) {
        tickets.put(ticket.getId(), ticket);
        saleStatistics.addTicket(ticket);
        saveData();
        return true;
    }
    
    public Ticket getTicketById(String id) {
        return tickets.get(id);
    }
    
    public boolean updateTicket(Ticket ticket) {
        if (tickets.containsKey(ticket.getId())) {
            tickets.put(ticket.getId(), ticket);
            saveData();
            return true;
        }
        return false;
    }
    
    // 日志管理相关方法
    public void addLog(LogEntry log) {
        logs.add(log);
        saveData();
    }
    
    public List<LogEntry> getAllLogs() {
        return new ArrayList<>(logs);
    }
    
    // 销售统计相关方法
    public SaleStatistics getSaleStatistics() {
        return saleStatistics;
    }
    
    // 数据持久化相关方法
    @SuppressWarnings("unchecked")
    public void loadData() {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(DATA_FILE))) {
            users = (Map<String, User>) ois.readObject();
            movies = (Map<String, Movie>) ois.readObject();
            halls = (Map<String, Hall>) ois.readObject();
            screenings = (Map<String, Screening>) ois.readObject();
            logs = (List<LogEntry>) ois.readObject();
            saleStatistics = (SaleStatistics) ois.readObject();
            tickets = (Map<String, Ticket>) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            // 如果文件不存在或出错，使用初始化的默认数据
            System.out.println("加载数据失败，使用默认数据");
        }
    }
    
    public void saveData() {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(DATA_FILE))) {
            oos.writeObject(users);
            oos.writeObject(movies);
            oos.writeObject(halls);
            oos.writeObject(screenings);
            oos.writeObject(logs);
            oos.writeObject(saleStatistics);
            oos.writeObject(tickets);
        } catch (IOException e) {
            System.out.println("保存数据失败：" + e.getMessage());
        }
    }
} 